package com.black.utils.commons.sp;

import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.util.Map;

/**
 * @author ylx
 */
public class SpElUtil
{
    private static final ExpressionParser PARSER = new SpelExpressionParser();

    /**
     * 解析SpEL表达式并返回结果
     * 根变量名默认root或context
     *
     * @param expression 表达式字符串
     * @param contextMap 上下文变量（可选）
     * @param clazz      返回值类型
     * @param <T>        泛型类型
     * @return 表达式解析后的结果
     */
    public static <T> T parse(String expression, Map<String, Object> contextMap, Class<T> clazz)
    {
        return parse(expression, "context", contextMap, clazz);
    }

    /**
     * 解析SpEL表达式并返回结果
     * 根变量名默认root
     * 可额外指定
     *
     * @param expression 表达式字符串
     * @param rootName   根变量名
     * @param contextMap 上下文变量（可选）
     * @param clazz      返回值类型
     * @param <T>        泛型类型
     * @return 表达式解析后的结果
     */
    public static <T> T parse(String expression, String rootName, Map<String, Object> contextMap, Class<T> clazz)
    {
        // 创建上下文
        StandardEvaluationContext context = new StandardEvaluationContext(contextMap);
        if (contextMap != null)
        {
            context.setVariable(rootName, contextMap);
        }
        // 解析表达式
        Expression exp = PARSER.parseExpression(expression);
        return exp.getValue(context, clazz);
    }

    /**
     * 解析SpEL表达式并返回结果（无上下文）
     *
     * @param expression 表达式字符串
     * @param clazz      返回值类型
     * @param <T>        泛型类型
     * @return 表达式解析后的结果
     */
    public static <T> T parse(String expression, Class<T> clazz)
    {
        return parse(expression, null, clazz);
    }
}
